WebKitDev.Core.Structures = {
    Dictionary : function() {
        /* private properties*/
        var DicElements = new Array();
        /*public properties*/

        /*Private methods*/
        function getElementIndex(key) {
            for (var i = 0; i < DicElements.length; i++) {
                if (DicElements[i].Key == key)
                    return i;
            }
            return -1;
        }

        /*public methods*/
        this.Add = function(key, value) {
            if (getElementIndex(key) < 0) {
                var elem = new WebKitDev.Core.Structures.Pair(key, value);
                DicElements.push(elem);
            } else
                throw new Error("WebKitDev.Core.Structures.Dictionary.Add:Ya existe un elemento con la clave " + key);

        }
        this.Delete = function(key) {
            var elem = getElementIndex(key);
            if (elem >= 0)
                DicElements.splice(elem, 1);
        }
        this.SetValue = function(key, value) {
            var index = getElementIndex(key);
            if (index >= 0)
                DicElements[index] = new WebKitDev.Core.Structures.Pair(key, value);
            else
                throw new Error("WebKitDev.Core.Structures.Dictionary.SetValue: El diccionario no contiene la clave " + key);
        }
        this.GetElement = function(key) {
            var index = getElementIndex(key);
            if (index >= 0)
                return DicElements[i];
            else
                throw new Error("WebKitDev.Core.Structures.Dictionary.GetElement: El diccionario no contiene la clave " + key);
        }
        this.GetValue = function(key) {
            var elem = GetElement(key);
            if (elem.Value)
                return elem.Value;
            else
                throw new Error("WebKitDev.Core.Structures.Dictionary.GetValue: El diccionario no contiene la clave " + key);
        }
        this.GetKey = function(value) {
            for (var i = 0; i < DicElements.length; i++) {
                if (DicElements[i].Value == value)
                    return DicElements[i].Key;
            }
            throw new Error("WebKitDev.Core.Structures.Dictionary.GetKey: El diccionario no contiene valor " + value);
        }
        this.GetElementsArray = function() {
            var elems = new Array();
            for (var i = 0; i < DicElements.length; i++) {
                elems.push(DicElements[i]);
            }
            return elems;
        }
        this.GetKeys = function() {
            var keys = new Array();
            for (var i = 0; i < DicElements.length; i++) {
                keys.push(DicElements[i].Key);
            }
            return keys;
        }
        this.GetValues = function() {
            var values = new Array();
            for (var i = 0; i < DicElements.length; i++) {
                values.push(DicElements[i].Value);
            }
            return values;
        }
    },
    Pair : function(key, value) {
        this.Key = key;
        this.Value = value;
        return this;
    },
    Url : function(url) {
        this.OriginalURL = url;
        var length = url.split('/');
        this.File = url.split('/')[length - 1];
        /* Tipo y protocolo */
        this.Protocol = null;
        this.Server = null;
        this.Port = null;
        this.Path = null;
        this.UrlType = null;
        var ini = url.split('/')[0];
        if (ini.indexOf(":") > 0) {
            this.UrlType = WebKitDev.Core.Enums.UrlType.Absolute;
            this.Protocol = ini.split(':')[0];
            var urlWOProtocol = url.split("://")[1];

            this.Server = urlWOProtocol.split("/")[0];
            if (this.Server.indexOf(':') > 0) {
                this.Port = this.Server.split(':')[1];
                this.server = this.Server.split(':')[0];
            }
            this.Path = urlWOProtocol.split("/");
            this.Path = this.Path.splice(1, 1);
            this.Path = this.Path.pop();
        } else {
            this.UrlType = WebKitDev.Core.Enums.UrlType.Relative;
            this.Path = url.split("/");
            this.Path = this.Path.splice(1, 1);
            this.Path = this.Path.pop();
        }
        this.GetPath = function() {
            return this.Path.join('/');
        }
    },
    Resource : function(name, url) {
        this.Url = new WebKitDev.Core.Structures.Url(url);
        this.Name = (name) ? name : WebKitDev.Core.MD5.getMD5(this.Url.OriginalURL);
        this.Status = WebKitDev.Core.Enums.ResourceStatus.Created;
    },
    /**
     * Instacia un nuevo objeto dbTable
     * @param {string} name Nombre de la tabla.
     * @param {Array{WebKitDev.Core.Structures.dbIndex}} indexes Array con los datos de indices de las tablas.
     * @return {WebKitDev.Core.Structures.dbTable}
     */
    dbTable : function(name, indexes) {
        this.Name = name;
        this.Indexes = indexes;
        return this;
    },
    /**
     * Instacia un nuevo objeto dbTable
     * @param {string} name nombre del campo.
     * @param {bool} primaryKey Indica si es clave primaria.
     * @param {bool} autoIncrement Indica si la clave primaria es autoincremental.
     * @param {bool} index Indica que es un indice de una tabla.
     * @param {bool} unique Indica que el indice es unico.
     * @param {string} indexName nombre del indice.
     * @return {WebKitDev.Core.Structures.dbTable}
     */
    dbIndex : function(name, primaryKey, autoIncrement, index, unique, indexName) {
        this.Name = name;
        this.PrimaryKey = (!primaryKey) ? false : true;
        this.AutoIncrement = (!autoIncrement) ? false : true;
        this.AutoIncrement = this.AutoIncrement && this.PrimaryKey;
        this.Index = (!index) ? false : true;
        this.Unique = (!unique) ? false : true;
        this.IndexName = (!indexName) ? name : indexName;
        return this;
    }
}
